package com.probeez.profiles.gsensor;

import static com.probeez.profiles.gsensor.WindowOrientationListener.TILT_POSITION_THERSHOLD;
import static com.probeez.profiles.plugin.PluginIntent.ACTION_TRIGGER_CONDITION;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

import com.probeez.profiles.plugin.PluginIntent;

public class EvalConditionService extends Service {
	public static final String STATE_POSITION = "state_position";
	
	private static final String PREF_POSITION_THRESHOLD = "position_threshold";
	private static final String PREF_FILENAME = "settings";

	static final String TAG = "SPGravity";
	/** to enable debug run 'adb shell setprop log.tag.SPPlugin DEBUG' and reinstall/restart the plugin */
	static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 
	
	/**
   * Class for clients to access.  Because we know this service always
   * runs in the same process as its clients, we don't need to deal with
   * IPC.
   */
  public class LocalBinder extends Binder {
  	EvalConditionService getService() {
          return EvalConditionService.this;
      }
  }

  /**
   * Handler class to listen for phone position/orientation changes. 
   */
	class OrientationHandler extends WindowOrientationListener {
		public OrientationHandler(Context context) {
	    super(context);
    }
		@Override
		public void onOrientationChanged(int rotation) {
		}
		@Override
		public void onPositionChanged(int position) {
			if (DEBUG) Log.d(TAG, "Got new position:"+position);
			Context context = EvalConditionService.this;
			PluginIntent intent = new PluginIntent(context, ACTION_TRIGGER_CONDITION);
			Bundle state = intent.getState();
			state.putInt(STATE_POSITION, position);
			intent.send();
		}

	}

	/** Flag indicating if the service has been started */
	private static boolean mStarted;
	/** Threshold of tilt up/down/intimidate detection */
	private static int mPositionThreshold = TILT_POSITION_THERSHOLD;
	/** Orientation handler instance created during starting of the service*/
	private static OrientationHandler mPositionHandler;
	/** Binder instance */
  private final IBinder mBinder = new LocalBinder();

	@Override
	public void onCreate() {
		super.onCreate();
		// restore position threshold
		SharedPreferences prefs = getSharedPreferences(PREF_FILENAME, MODE_PRIVATE);
		mPositionThreshold = prefs.getInt(PREF_POSITION_THRESHOLD, TILT_POSITION_THERSHOLD);
		// due to complains on service got stopped after hours and possible bug in 2.3 about 
		// onStartCommand not being called, doing listener initialization in onCreate
		if (!mStarted) {
			if (DEBUG) Log.i(TAG, "Subscribed on sensor events");
			mPositionHandler = new OrientationHandler(this);
			mPositionHandler.setPositionThreshold(mPositionThreshold);
			mPositionHandler.enable();
		}
		mStarted = true;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (DEBUG) Log.i(TAG, "Service received start id " + startId + ": " + intent);
		// We want this service to continue running until it is explicitly
		// stopped, so return sticky.
		return START_STICKY;
	}

	@Override
	public void onDestroy() {
		mStarted=false;
		if (mPositionHandler!=null) {
			mPositionHandler.disable();
			mPositionHandler = null;
			if (DEBUG) Log.i(TAG, "Unsubscribed from sensor events");
		}
		if (DEBUG) Log.i(TAG, "Service destroyed");
	}

	@Override
  public IBinder onBind(Intent intent) {
    return mBinder;
  }

	public static boolean isStarted() {
		return mStarted;
	}

	public int getPositionThreshold() {
		return mPositionThreshold;
	}

	/**
	 * Sets threshold of tilt up/down/intimidate detection.
	 *  
	 * @param threshold a threshold value to be set
	 */
	public void setPositionThreshold(int threshold) {
		// store to preference file
		SharedPreferences prefs = getSharedPreferences(PREF_FILENAME, MODE_PRIVATE);
		Editor editor = prefs.edit();
		editor.putInt(PREF_POSITION_THRESHOLD, threshold);
		editor.commit();
		// keep locally
		mPositionThreshold = threshold;
		// set to orientation handler
		if (mPositionHandler!=null) {
			mPositionHandler.setPositionThreshold(threshold);
		}
	}

}
